﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Render
{
    class PerfCounter : Microsoft.Xna.Framework.DrawableGameComponent
    {
        Game game;

        //FPS variables
        private int totalFrames;
        private double currentFPS;
        private double averageFPS;
        private double highestFPS;
        private double lowestFPS = 999;

        //Frame Time variables
        private double lastFrameTime;
        private double averageFrameTime;
        private double bestFrameTime = 999;
        private double worstFrameTime;

        //Sprite text
        SpriteBatch textSprite;
        private SpriteFont font;
        private Vector2 fontPosition;
        private string output;

        private bool active;

        public bool Active
        {
            get { return active; }
            set { active = value; }
        }

        public PerfCounter(Game game): base(game)               
        {
            this.game = game; 
        }               

        public override void Initialize() 
        {
            fontPosition = new Vector2(20, 20);
            active = false;

            base.Initialize();               
        }

        protected override void LoadContent()
        {
            textSprite = new SpriteBatch(game.GraphicsDevice);
            font = game.Content.Load<SpriteFont>("fpsFont");
            

            base.LoadContent();
        }

        public void ResetStats()
        {
            //FPS variables
            totalFrames = 0;
            currentFPS = 0;
            averageFPS = 0;
            highestFPS = 0;
            lowestFPS = 999;

            //Frame Time variables
            lastFrameTime = 0;
            averageFrameTime = 0;
            bestFrameTime = 999;
            worstFrameTime = 0;

        }

        public override void Update(GameTime gameTime)
        {
            // increment frame counter
            totalFrames++;

            //fps calculations
            currentFPS = 1 / gameTime.ElapsedGameTime.TotalSeconds;
            averageFPS = totalFrames / gameTime.TotalGameTime.TotalSeconds;

            // highest fps
            if (gameTime.ElapsedGameTime.TotalSeconds != 0)
                if (currentFPS > highestFPS) highestFPS = currentFPS;

            // lowest fps
            if (currentFPS < lowestFPS) lowestFPS = currentFPS;

            //frame time calculations
            lastFrameTime = 1000 / currentFPS;
            averageFrameTime = gameTime.TotalGameTime.TotalMilliseconds / totalFrames;

            // best frame time
            if (lastFrameTime < bestFrameTime && lastFrameTime != 0) bestFrameTime = lastFrameTime;

            // worst
            if (lastFrameTime > worstFrameTime) worstFrameTime = lastFrameTime;

            base.Update(gameTime);
        }               

        public override void Draw(GameTime gameTime)
        {
            if (active)
            {
                //build the output string.
                output = "FPS Stats (Higher is better)\nCurrentFPS: " + currentFPS.ToString() +
                "\nAverage FPS: " + averageFPS.ToString() +
                "\nHighest FPS: " + highestFPS.ToString() +
                "\nLowest FPS: " + lowestFPS.ToString() +
                "\n\nFrame Time Stats (Lower is better) \nLast Frame Time: " + lastFrameTime.ToString() +
                "\nAverage Frame Time: " + averageFrameTime.ToString() +
                "\nBest Frame Time: " + bestFrameTime.ToString() +
                "\nWorsts Frame Time: " + worstFrameTime.ToString();

                textSprite.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
                textSprite.DrawString(font, output, fontPosition, Color.White);
                textSprite.End();
            }
        } 
    }
}
